#ifndef MODBUS_H
#define MODBUS_H

#include "user_global.h"
#include "global.h"
#include "config.h"

extern unsigned char server_address; //设备地址

//------------------------------------------
// RW-BIT
//------------------------------------------
typedef struct RW_BIT{
    bit z0_valid:1;  // Z0有效
    bit z1_valid:1;  // Z1有效
    bit z2_valid:1;  // Z2有效
    bit ignore_level_sensor:1;  // 忽略液面探测错误
    bit no_rinsing_home:1;  // 清洗时不复位
    bit independent_rinse:1;  // 独立清洗单元
    bit no_rinsing_home_x:1;  // 清洗时不复位X轴
    bit no_rinsing_home_y:1;  // 清洗时不复位Y轴

}RW_BIT;
extern  RW_BIT rw_bit;
#define RW_BIT_FIRST        ((uchar*)&rw_bit)
#define RW_BIT_COUNT        0x08

//------------------------------------------
// RW-BIT
//------------------------------------------
__packed typedef struct RO_BIT{
    bit x_at_home:1; // Z在原点
    bit y_at_home:1;  // Y在原点
    bit x_home_1:1;  // X在原点1
    bit x_home_2:1;  // X在原点2
    bit z1_insuficient_solution:1;  // 清洗液不足报警(1)
    bit z1_sewage_full:1;  // 废液满报警(1)
    bit z1_pressure_high:1;  // 压力超上限报警(1)
    bit z1_pressure_low:1;  // 压力超下限报警(1)
    bit z2_insuficient_solution:1;  // 清洗液不足报警(1)
    bit z2_sewage_full:1;  // 废液满报警(1)
    bit z2_pressure_high:1;  // 压力超上限报警(1)
    bit z2_pressure_low:1;  // 压力超下限报警(1)
}RO_BIT;
extern  RO_BIT ro_bit;
#define RO_BIT_FIRST                        ((uchar*)&ro_bit)
#define RO_BIT_COUNT                        0x0C

//==========================================================
// RW-WORD
//==========================================================
__packed typedef struct RW_WORD
{
    ushort XMAX_SPEED ;     //X 最高速度。
    long X_MAX_DISTANCE;     //X 最大行程，步。
    ushort YMAX_SPEED;       //Y 最高速度。
    long Y_MAX_DISTANCE; //Y 最大行程，步。
    short X_REF_SPEED; //X 参考系速度。
    long X_REF_POS;  //X 参考系坐标。
    short PICKUP_CUP_DISTANCE;//抓放测试杯 Y 相对位移。
    ushort ACTION;//当前执行指令。
    long X_TARGET_1;//目标 X 坐标 1。
    long Y_TARGET_1;//目标 Y 坐标 1。
    long Z_TARGET_1;//目标 Z 坐标 1。
    short REAGENT_VOLUME;//吸样/加样量，x0.01ul。
    ushort REAGENT_BOTTLE_TYPE;
    long X_TARGET_2;//目标 X 坐标 2。
    long Y_TARGET_2;//目标 Y 坐标 2。
    long Z_TARGET_2;//目标 Z 坐标 2
    RECT range;        // 运行范围
    RECT block[MAX_BLOCK_COUNT];        // 禁止运行范围
}RW_WORD;
extern RW_WORD rw_word;
#define RW_WORD_FIRST       ((ushort*)&rw_word.XMAX_SPEED)
#define RW_WORD_END         ((ushort*)&rw_word.BLOCK_Y_MAX)
#define RW_WORD_COUNT       (0x29)

//==========================================================
// RO-WORD
//==========================================================
__packed typedef struct RO_WORD{
    long X_POS;               // 当前 X 坐标，步。
    ushort X_SPEED;            //当前 X 速度，0.01 rad/sec
    long Y_POS;                //当前 Y 坐标，步
    ushort Y_SPEED;             //当前 y 速度，0.01 rad/sec
    ushort X_DURATION;          //X 运动经过的时间，ms。
    ulong X_DISTANCE;           //X 运动经过的距离，步。
    ushort Y_DURATION;           //Y 运动经过的时间，ms。
    ulong Y_DISTANCE;            //Y 运动经过的距离，步。
    ushort REAGENT_RESIDUAL_VOLUME; //最后一次检测到的试剂剩余量，ul。
}RO_WORD;
extern RO_WORD ro_word;
#define RO_WORD_FIRST       ((ushort*)&ro_word.X_POS)
#define RO_WORD_END         ((ushort*)&ro_word.REAGENT_RESIDUAL_VOLUME)
#define RO_WORD_COUNT       0x0D

//------------------------------------------
// 事件
//------------------------------------------
#define MAX_EVENT_COUNT                                64                // 2^n
#define MAX_EVENT_MASK                                (MAX_EVENT_COUNT-1)
// 接收事件
#define EVENT_RECEIVED                                0x80        // 接收事件
#define EVENT_BROADCAST                               0x40        // 接收到广播消息
#define EVENT_LISTEN_ONLY                             0x20        // 当前处于只听模式
#define EVENT_CHARRACTER_OVERRUN                      0x10        // 字符过载
#define EVENT_COMMUNICATION_ERROR                     0x02        // 通讯错误
// 发送事件
#define EVENT_SENT                                    0x40        // 发送事件
//#define EVENT_LISTEN_ONLY                           0x20        // 当前处于只听模式
#define EVENT_WRITE_TIMEOUT                           0x10        // 写超时
#define EVENT_EXCEPTION                               0x80        // 异常应答
#define EVENT_BUSY_EXCEPTION                          0x04        // 错误代码 5-6
#define EVENT_ABORT_EXCEPTION                         0x02        // 错误代码 4
#define EVENT_READ_EXCEPTION                          0x01        // 错误代码 1-3

// 进入只听模式事件
#define EVENT_ENTER_LISTEN_ONLY     0x04    // 进入只听模式事件

//------------------------------------------
// 异常应答代码
//------------------------------------------
#define ILLEGAL_FUNCTION            0x01
#define ILLEGAL_DATA_ADDRESS        0x02
#define ILLEGAL_DATA_VALUE          0x03
#define SERVER_DEVICE_FAILURE       0x04
#define ACKNOWLEDGE                 0x05
#define SERVER_DEVICE_BUSY          0x06
#define MEMORY_PARITY_ERROR         0x08
#define GATEWAY_PATH_UNAVAILABLE    0x0A
#define GATEWAY_TARGET_NO_RESPONSE  0x0B

//------------------------------------------
// 文件
//------------------------------------------
#define FILE_COUNT              1
#define MAX_FILE_REQUEST        2       // 一次请求最大的子记录访问数量

#define FILE_BUFFER_SIZE        256
#define FILE_BUFFER_MASK        (FILE_BUFFER_SIZE-1)

extern ushort xdata file_buf[FILE_BUFFER_SIZE];
//------------------------------------------
// 诊断
//------------------------------------------
extern ushort  diagnostic;
extern ushort  bus_message_count;      // 总线上消息数量
extern ushort  bus_error_count;        // 总线上通讯错误数量
extern ushort  bus_exception_count;      // 总线上异常应答数量
extern ushort  server_message_count;        // 下位机消息数量
extern ushort  server_no_response_count;        // 下位机未响应消息数量
extern ushort  server_exception_count;        // 下位机异常应答消息数量
extern ushort  server_status;
extern uchar   program_status;
extern ushort  server_busy_count;
extern ushort  bus_char_overrun_count;

extern ushort  server_status;             // 下位机状态
extern uchar program_status;

extern bit ps_listen_only;                    // 处于只听模式
extern bit ps_server_busy;                  // 设备忙

extern uchar event_count;                                        // 事件记数值, event_count索引的event_log为当前事件
extern uchar event_log[MAX_EVENT_COUNT];        // 事件记录

void register_init(void);

void Read_Address(void);//获取id
void Device_Init(void);//初始化id

void No_Response(void);
void Exception_Response(uchar err);
void Response(void);

uchar Read_RW_bit(ushort addr, uchar n);
uchar Read_RO_bit(ushort addr, uchar n);
void write_bits(uchar *bits, ushort addr, uchar val, uchar n);
void Write_bit(ushort addr, uchar val, uchar n);
void Write_RO_bit(ushort addr, uchar val, uchar n);
ushort Read_RW_word(ushort addr);
ushort Read_RO_word(ushort addr);
void Write_word(ushort addr, ushort val);

void Log_Event(uchar event);//事件记录
void Process_Request(void);//处理上位机请求

// 读取异常状态
uchar Read_Exception(void);
// 诊断
void Diagnose(void);

void Read_Identification(void);

void Process_Main_Loop(void);
void Main_Loop(void);

#if FILE_COUNT
// 文件操作
void Reset_File(uchar fid);
void Append_File(uchar fid, ushort *rec, ushort n);
ushort Read_File(uchar fid, ushort addr);
void Write_File(uchar fid, ushort addr, ushort val);
ushort File_Size(uchar fid);
#endif//FILE_COUNT

#endif
